package com.onlyMe.view.world
{
	import com.flesler.componentas.core.Component;
	import com.onlyMe.globals.config;
	import com.onlyMe.view.base.BaseView;
	import com.onlyMe.view.world.components.ComponentViewCreator;
	import com.onlyMe.view.world.objects.IsleObjectView;
	import com.onlyMe.view.world.objects.IsleObjectViewCreator;
	import com.onlyMe.view.world.tiling.TileAssetCreator;
	import com.onlyMe.view.world.tiling.TileView;
	import com.onlyMe.world.Isle;
	import com.onlyMe.world.IsleEvent;
	import com.onlyMe.world.objects.IsleObject;
	import com.onlyMe.world.tiling.Tile;
	import com.onlyMe.world.tiling.TileGrid;
	import com.qb9.flashlib.math.QMath;
	import com.qb9.flashlib.tasks.TaskRunner;
	import com.qb9.flashlib.utils.DisplayUtil;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.sampler.getSize;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	
	// TODO: Create new views when object are removed and readded or not?
	// TODO: Show views
	
	public final class IsleView extends BaseView
	{
		private var isle:Isle;
		private var viewMap:Dictionary = new Dictionary();
		
		private var tasks:TaskRunner;
		private var objectCreator:IsleObjectViewCreator;
		private var tileAssetCreator:TileAssetCreator;
		
		public function IsleView(isle:Isle)
		{
			this.isle = isle;
			
			init();
		}
		
		private function init():void
		{
			tasks = new TaskRunner(this);
			tasks.start();
			
			isle.addEventListener(IsleEvent.OBJECT_ADDED, addObject);
			isle.addEventListener(IsleEvent.OBJECT_REMOVED, removeObject);
			isle.addEventListener(IsleEvent.READY, initGrid);
			
			objectCreator = new IsleObjectViewCreator(tasks);
			tileAssetCreator = new TileAssetCreator();
		}
		
		private function initGrid(e:Event):void
		{
			// DEBUG
			var t:int = getTimer();
			
			var bd:BitmapData = new BitmapData(2800, 2800);
			var temp:Sprite = new Sprite();
			
			var grid:TileGrid = isle.grid;
			var gw:int = grid.width;
			var gh:int = grid.height;
			
			var tw:Number = config.tiles.width;
			var th:Number = config.tiles.height;
		
			for (var i:int = 0; i < gw; i++)
			{
				for (var j:int = 0; j < gh; j++)
				{
					var tile:Tile = grid.getTileAt(i, j);
					if (!tile) 
						continue;
					
					var asset:DisplayObject = tileAssetCreator.create(tile.type);
					var view:TileView = new TileView(tile, null);
					view.x = tw * i;// + (gh - j) * Math.cos(angle) * tw;
					view.y = th * j;
					addChild(view);
					
					viewMap[tile] = view;
					
					asset.x = view.x;
					asset.y = view.y;
					temp.addChild(asset);
				}
			}
			
			bd.draw(temp);
			addChildAt(new Bitmap(bd), 0);
			// DEBUG
			trace(getTimer()-t);
		}
		
		private function addObject(e:IsleEvent):void
		{
			var object:IsleObject = e.object;
			var tile:Tile = isle.getTile(object);
			
			var container:Sprite = new Sprite();
			viewMap[tile].addChild(container);

			viewMap[object] = objectCreator.createFrom(object, container);
		}
		
		private function removeObject(e:IsleEvent):void
		{
			var object:IsleObject = e.object;
			var view:IsleObjectView = viewMap[object];
			var tile:Tile = isle.getTile(object);
			
			viewMap[tile].removeChild(view.container);
			delete viewMap[object];
			
			view.destroy();
		}
		
		override public function destroy():void
		{
			tasks.dispose();
			tasks = null;
			
			objectCreator.destroy();
			objectCreator = null;
			
			viewMap = null;
			isle = null;
			tileAssetCreator = null;
			super.destroy();
		}
	}
}